﻿using AutoMapper;
using Common.Result;
using IService;
using Model.Dto.Dish;
using Model.Dto.Setmeal;
using Model.Entitys;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Service
{
    public class SetmealService : ISetmealService
    {
        private readonly ISqlSugarClient _db;
        private readonly IMapper _mapper;
        public SetmealService(ISqlSugarClient db, IMapper mapper)
        {
            _db = db;
            _mapper = mapper;
        }

        /// <summary>
        /// 删除套餐根据ids
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        public async Task<bool> DeleteSetmealByIdsAsync(List<long> ids)
        {
            var res = await _db.Deleteable<Setmeal>()
                .EnableQueryFilter()
                .In(ids).IsLogic().ExecuteCommandAsync();
            if (res > 0) return true;
            return false;
        }

        public async Task<bool> EdiSetmealByIdAsync(SetmealEdit setmealEdit, long id)
        {
            _db.Ado.BeginTran();
            Setmeal setmeal = _mapper.Map<Setmeal>(setmealEdit);
            setmeal.UpdateUser = id;
            //先删除关联菜品信息 非逻辑删除
            await _db.Deleteable<SetmealDish>().Where(it=>it.SetmealId==setmealEdit.Id.ToString()).ExecuteCommandAsync();
            //更新忽略null并且忽略默认值
            var update = await _db.Updateable(setmeal).IgnoreColumns(ignoreAllNullColumns: true, ignoreAllDefaultValue: true)
                .Where(it => it.Id == setmeal.Id).ExecuteCommandAsync();
            //重新插入套餐菜品信息
            var insert = await InsertSetmealDishesAsync(_mapper.Map<List<SetmealDish>>(setmealEdit.SetmealDishes), id, setmeal.Id);
            if (insert.Count > 0 && update > 0)
            {
                //提交事务
                _db.Ado.CommitTran();
                return true;
            }
            return false;
        }

        public async Task<bool> EditStatusByIdsAsync(List<long> ids, int status, long userId)
        {
            _db.Ado.BeginTran();//开启事务
            // 将 ids 的值赋给 Setmeals 集合的 id 属性
            List<Setmeal> Setmeals = ids.Select(id => new Setmeal { Id = id }).ToList();
            //同时赋值status
            Setmeals.ForEach(d => { d.UpdateUser = userId; d.Status = status; });
            //只更新status
            var col = await _db.Updateable(Setmeals).UpdateColumns(it => new { it.Status, it.UpdateTime, it.UpdateUser })
                .ExecuteCommandAsync();
            _db.Ado.CommitTran();//提交事务
            if (col > 0) return true;
            return false;
        }

        public async Task<PageInfo> GetPageInfoAsync(int page, int pageSize, string? name)
        {
            RefAsync<int> total = 0;
            //联合category表查询分类名
            var Setmeals = await _db.Queryable<Setmeal>()
                              .LeftJoin<Category>((s, cate) => s.CategoryId == cate.Id)
                              .WhereIF(!string.IsNullOrEmpty(name), (s, cate) => s.Name.Contains(name))
                              .Select((s, cate) => new SetmealRes
                              {
                                  Id = s.Id,
                                  Name = s.Name,
                                  CategoryName = cate.Name
                              }, true)//其余字段自动映射
                              .ToPageListAsync(page, pageSize, total);
            return new PageInfo
            {
                Data = Setmeals,
                Total = total
            };
        }

        public async Task<SetmealRes> GetSetmealDtoByTdAsync(long id)
        {
            SetmealRes setmealRes = await _db.Queryable<Setmeal>().LeftJoin<Category>((d, cate) => d.CategoryId == cate.Id)
                .Where((d, cate) => d.Id == id)
                .Select((d, cate) => new SetmealRes
                {
                    Id = d.Id,
                    Name = d.Name,
                    CategoryName = cate.Name,
                    CategoryId = cate.Id,
                }, true)//其余字段自动映射
                .FirstAsync();
            setmealRes.SetmealDishes = await _db.Queryable<SetmealDish>().Where(it => it.SetmealId == id.ToString()).ToListAsync();
            return setmealRes;
        }
        /// <summary>
        /// Getsetmeals
        /// </summary>
        /// <param name="setmeal"></param>
        /// <returns></returns>
        public async Task<List<SetmealRes>> GetsetmealsAsync(SetmealQuery setmealQuery)
        {
            var setmeals= await _db.Queryable<Setmeal>()
                 .Where(it=>it.CategoryId== setmealQuery.CategoryId)
                 .WhereIF(setmealQuery.Status!=null,it=>it.Status == setmealQuery.Status)
                 .OrderBy(it=>it.UpdateTime, OrderByType.Desc).ToListAsync();
            return _mapper.Map<List<SetmealRes>>(setmeals);
        }

        public async Task<bool> SaveWithDishAsync(SetmealAdd setmealAdd, long id)
        {
            //开启事务
            _db.Ado.BeginTran();
            var Setmeal = _mapper.Map<Setmeal>(setmealAdd);
            //设置默认状态
            Setmeal.Status = 1;
            Setmeal.CreateUser = id;
            Setmeal.UpdateUser = id;
            //保存菜品的基本信息到菜品表dish
            var setmealId = await _db.Insertable(Setmeal).ExecuteReturnSnowflakeIdAsync();
            //保存菜品和套餐关联关系到表SetmealDish
            await InsertSetmealDishesAsync(_mapper.Map<List<SetmealDish>>(setmealAdd.SetmealDishes), id, setmealId);
            //提交事务
            _db.Ado.CommitTran();
            return true;
        }
        /// <summary>
        /// 插入
        /// </summary>
        private async Task<List<long>> InsertSetmealDishesAsync(List<SetmealDish> setmealDishes, long id, long setmealId)
        {
            //设置setmealId和user
            foreach (var item in setmealDishes)
            {
                item.SetmealId = setmealId.ToString();
                item.Sort = 0;
                item.CreateUser = id;
                item.UpdateUser = id;
            }
            //保存菜品和套餐关联关系到表SetmealDish
            return await _db.Insertable(setmealDishes).ExecuteReturnSnowflakeIdListAsync();
        }
    }
}
